package com.itheima.tanhua.service;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.itheima.autoconfig.template.HuanXinTemplate;
import com.itheima.autoconfig.template.SmsTemplate;
import com.itheima.tanhua.enums.Constants;
import com.itheima.tanhua.exception.ConsumException;
import com.itheima.tanhua.pojo.db.User;
import com.itheima.tanhua.api.db.UserApi;
import com.itheima.tanhua.utils.AppJwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 业务逻辑处理类
 */
@Service
public class UserService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @DubboReference
    private UserApi userService;

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    /**
     * 发送手机验证码
     * @param phone 前端发送的手机号
     */
    public void sendMsg(String phone) {

        /**
         * 登录的步骤
         * 1.生成验证码
         * 2.将验证码存入redis
         */
        //判断验证码是否存在
        String redisKey="CODE_"+phone;
        String  redisCode = redisTemplate.opsForValue().get(redisKey);

        if (StrUtil.isNotBlank(redisCode)){
             throw new ConsumException("验证码未失效");
        }else {
            //生成验证码
//        int code = RandomUtil.randomInt(6);
            String code="666666";
            //发送验证码
           // smsTemplate.sendSms(phone,code);

            //获取redis 的key
            redisTemplate.opsForValue().set(redisKey, code);
        }

    }

    /**
     * 手机号验证码验证
     * @param param
     * @return
     */
    public Map Verification(Map<String, String> param) {

        //1.首先获取手机号和验证码
        String phone = param.get("phone");
        String code = param.get("verificationCode");

        //2.从redis中获取code的值
        //2.1 获取键值
        String redisKey="CODE_"+phone;

        String redisCode = redisTemplate.opsForValue().get(redisKey);
       if (StrUtil.isBlank(redisCode)){
           throw new ConsumException("验证码不存在,请重新发送!");
       }

        //3.比较code和redisCode的值是否相等
        if (!StrUtil.equals(code,redisCode)){
            //验证码不相等
            throw new ConsumException("验证码不相等");
        }
        //验证码相等 登录成功
        //根据phone去查询用户
        User user = userService.getByPhone(phone);
        boolean isNew =false;
        if (ObjectUtil.isEmpty(user)){
            //新用户
            //创建对象
            user=new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
            user.setCreated(new Date());
            user.setUpdated(new Date());
            Long id = userService.save(user);
            user.setId(id);
            isNew=true;
            //注册环信用户
            String hxUser = "hx"+user.getId();
            Boolean create = huanXinTemplate.createUser(hxUser, Constants.INIT_PASSWORD);
            if(create) {
                user.setHxUser(hxUser);
                user.setHxPassword(Constants.INIT_PASSWORD);
                userService.update(user);
            }
        }
        //4.登录成功后生成token  使用固定的id   想要获取用户id 需要远程调用方法
        String token = AppJwtUtil.getToken(user.getId());
        //5.判断isNew的值 想要获取isNew的值就要查询数据库中是否存在数据
        //返回值 token  还有isNew
        Map map=new HashMap();
        map.put("token",token);
        map.put("isNew",isNew);
        redisTemplate.delete(redisKey);
        return map;
    }

    /**
     * 校验token
     *
     * @param token
     */
    public Long tokenCheck(String token) {
        //第一步校验taken
        Claims claims = AppJwtUtil.getClaimsBody(token);
        //有四种状态0 ,-1 有效      1 ,2 过期
        int verifyToken = AppJwtUtil.verifyToken(claims);
        if (verifyToken == 1 || verifyToken == 2) {
            //token 已经失效
            throw new ConsumException("token已经失效");
        }
        return Convert.toLong(claims.get("id"));
    }

}
